<?php

class ArrayProcessor_Translator  {
	
	public static function structureToFunction ($parent, $structure, $elementReplacer)  {
		$attributes = array();
		$contentElements = array();
		
		if (!is_null($structure[ArrayProcessor_XMLElements::ELE_GENERAL]))  {
		foreach ($structure[ArrayProcessor_XMLElements::ELE_GENERAL] as $key=>$value)  {
			if ($key == PropertySetter::PROPERTY_ATTRIBUTE)  {
				$rii = new RecursiveIteratorIterator(new RecursiveArrayIterator($value));
				
   				foreach ($rii as $innerKey=>$innerValue)  {
   					$flat[$innerKey] = $innerValue;
   				}
   				
   				$attributes[PropertySetter::PROPERTY_ATTRIBUTE] = $flat;
   				$flat = array();

			}
			else if ($key == PropertySetter::PROPERTY_ELEMENT)  {
				$rii = new RecursiveIteratorIterator(new RecursiveArrayIterator($value));
   				foreach ($rii as $innerKey=>$innerValue)  {
   					$flat[$innerKey] = $innerValue;
   				}
   				
   				$contentElements[PropertySetter::PROPERTY_ELEMENT] = $flat;
   				$flat = array();
			}
		}
		}
		
		$functionCalls = array();
		
		$mergedArray = array_merge($attributes, $contentElements);

		$structureFlat = $structure[ArrayProcessor_XMLElements::ELE_STRUCTURE];

		if (!empty($structureFlat))  {
				if (!empty($value))  {
					if (count($structureFlat[ArrayProcessor_XMLElements::ELE_ELEMENT]) > 1 && is_int(key($structureFlat[ArrayProcessor_XMLElements::ELE_ELEMENT])))  {
						foreach ($structureFlat[ArrayProcessor_XMLElements::ELE_ELEMENT] as $key=>$value)  {
							self::recursiveWalk($parent, $value, $elementReplacer, $mergedArray);
						}
					}
					else  {
						self::recursiveWalk($parent, $structureFlat[ArrayProcessor_XMLElements::ELE_ELEMENT], $elementReplacer, $mergedArray);
					}
				}
		}		
	}
	
	private static function recursiveWalk ($parent, $value, $rootElement, $mergedArray)  {
		
		$parentElement = null;
		
		if (!is_int(key($value)))  {
		
		$elementRelated = self::getElementRelatedAttributes($rootElement, $value);
			
		$elementAttributes = array_merge($elementRelated, $mergedArray);
			
		$elementAttributes = self::transformArray($elementAttributes);
			
		$class = self::translateHTMLTag($rootElement);
			
		$parentElement = new $class($parent, $elementAttributes);
		
		}
		
		foreach ($value as $element=>$data)  {
			$intElement = null;
			if (is_int($element))  {
				$intElement = true;
				$element = $rootElement;
			}
			if (is_array($data) && self::translateHTMLTag($element))  {
				if (is_int($element) || $intElement)  {
					self::recursiveWalk($parent, $data, $rootElement, array());
				}
				else  {
					self::recursiveWalk($parentElement, $data, $element, array());
				}
			}
			else if (self::translateHTMLTag($element)) {
				
				$elementRelated = self::getElementRelatedAttributes($element, $data);
				$elementAttributes = array_merge($elementRelated);
				$elementAttributes = self::transformArray($elementAttributes);

				$class = self::translateHTMLTag($element);
				
				if (is_null($parentElement))  {
					$parentElement = $parent;
				}
				$parentContent = new $class($parentElement, $elementAttributes);
				
				if (is_string($data) && strtolower($class) != ArrayProcessor_XMLElements::ARRAY_ELE_CONTENT)  {
					$class = self::translateHTMLTag(ArrayProcessor_XMLElements::ARRAY_ELE_CONTENT);
					new $class($parentContent, $elementAttributes);
				}
			}
			
		}
	}
	
	private static function getElementRelatedAttributes ($element, $structure)  {
		
		$class = self::translateHTMLTag($element);

		if ($class)  {

		$attributes = $class::getAttributes();
		
		$elementRelatedAttributes = array();
		if (is_array($structure))  {
		foreach ($structure as $element=>$data)  {
			if (in_array($element, $attributes, true))  {
				$elementRelatedAttributes[$element] = $data;
			}
		}
		}
		else  {
			$elementRelatedAttributes[ArrayProcessor_XMLElements::ARRAY_ELE_CONTENT] = $structure;
		}
		
		
		return $elementRelatedAttributes;
		}
	}
	
	private static function transformArray ($elementRelated)  {
		$elementAttributes = array();

		if (array_key_exists(ArrayProcessor_XMLElements::ARRAY_ELE_CONTENT, $elementRelated))  {
			$content[ArrayProcessor_XMLElements::ARRAY_ELE_CONTENT] = $elementRelated[ArrayProcessor_XMLElements::ARRAY_ELE_CONTENT];

			if (array_key_exists(PropertySetter::PROPERTY_ELEMENT, $elementRelated))  {
				$content = self::getMultipleGeneral($content, $elementRelated, PropertySetter::PROPERTY_ELEMENT);
				unset($elementRelated[PropertySetter::PROPERTY_ELEMENT]);
			}
			
			$elementAttributes[PropertySetter::PROPERTY_ELEMENT] = $content;
			unset ($elementRelated[ArrayProcessor_XMLElements::ARRAY_ELE_CONTENT]);
		}
		if (array_key_exists(PropertySetter::PROPERTY_ELEMENT, $elementRelated))  {
			$content = self::getMultipleGeneral($content, $elementRelated, PropertySetter::PROPERTY_ELEMENT);
			unset($elementRelated[PropertySetter::PROPERTY_ELEMENT]);
		}
		
		if (!empty($elementRelated))  {
			$generalAttributes = array();
			if (array_key_exists(PropertySetter::PROPERTY_ATTRIBUTE, $elementRelated))  {
				$generalAttributes = self::getMultipleGeneral($generalAttributes, $elementRelated, PropertySetter::PROPERTY_ATTRIBUTE);
				unset($elementRelated[PropertySetter::PROPERTY_ATTRIBUTE]);
			}
			
			$attributes = array_merge($generalAttributes, $elementRelated);
			$elementAttributes[PropertySetter::PROPERTY_ATTRIBUTE] = $attributes;
		}
		
		return $elementAttributes;
	}
	
	private static function getMultipleGeneral ($content, $inputArray, $property)  {
		foreach ($inputArray[$property] as $key=>$value)  {
			$content[$key] = $value;
		}
		
		return $content;
	}
	
	private static function translateHTMLTag ($tag)  {
		
		$function = false;
		
		if (is_int($tag))  {
			return $function;
		}
		
		switch ($tag)  {
			case HTML_ALink::HTML_ALINK:
				$function = 'HTML_ALink';
				break;
			case HTML_Div::HTML_DIV:
				$function = 'HTML_DIV';
				break;
			case HTML_Fieldset::HTML_FIELDSET:
				$function = 'HTML_Fieldset';
				break;
			case HTML_Form::HTML_FORM:
				$function = 'HTML_Form';
				break;
			case HTML_Image::HTML_IMAGE:
				$function = 'HTML_Image';
				break;
			case HTML_LI::HTML_LI:
				$function = 'HTML_LI';
				break;
			case HTML_Object::HTML_OBJECT:
				$function = 'HTML_Object';
				break;
			case HTML_OL::HTML_OL:
				$function = 'HTML_OL';
				break;
			case HTML_Option::HTML_OPTION:
				$function = 'HTML_Option';
				break;
			case HTML_Select::HTML_SELECT:
				$function = 'HTML_Select';
				break;
			case HTML_Span::HTML_SPAN:
				$function = 'HTML_Span';
				break;
			case HTML_Table::HTML_TABLE:
				$function = 'HTML_Table';
				break;
			case HTML_TableRow::HTML_TABLEROW:
				$function = 'HTML_TableRow';
				break;
			case HTML_UL::HTML_UL:
				$function = 'HTML_UL';
				break;
			case HTML_FormElements_Button::HTML_BUTTON:
				$function = 'HTML_FormElements_Button';
				break;
			case HTML_FormElements_Input::HTML_INPUT:
				$function = 'HTML_FormElements_Input';
				break;
			case HTML_TableElements_TableData::HTML_TABLEDATA:
				$function = 'HTML_TableElements_TableData';
				break;
			case HTML_TableElements_TableHead::HTML_TABLEHEAD:
				$function = 'HTML_TableElements_TableHead';
				break;
			case Content::CONTENT:
				$function = 'Content';
				break;
		}
		
		return $function;
	}
	
}